﻿using System;
using System.Collections.Generic;
using System.Text;
using NGinnBPM.Lib.Schema;
using NGinnBPM.Lib.Data;
using NGinnBPM.Lib.Interfaces;
using NGinnBPM.Lib.Exceptions;
using NGinnBPM.Runtime.Events;
using NGinnBPM.Runtime;
using NLog;
using System.Runtime.Serialization;

namespace NGinnBPM.Runtime.Tasks
{
    [Serializable]
    [DataContract]
    public class ReceiveMessageTaskInstance : AtomicTaskInstance
    {
        private string _messageCorrelationId;

        [DataMember]
        [TaskParameter(IsInput=true, Required=true, DynamicAllowed=true)]
        public string MessageCorrelationId
        {
            get { return _messageCorrelationId; }
            set { _messageCorrelationId = value; }
        }



        public override void Enable(Dictionary<string, object> inputData)
        {
            if (MessageCorrelationId == null || MessageCorrelationId.Length == 0)
            {
                MessageCorrelationId = string.Format("{0}_{1}", ProcessInstanceId, TaskId);
            }
            base.Enable(inputData);
            log.Info("Registering message correlation id {0}", MessageCorrelationId);
            Context.MessageCorrelationIdResolver.RegisterMapping(MessageCorrelationId, InstanceId);
        }

        public override void Cancel()
        {
            if (Status == TaskStatus.Cancelled)
            {
                log.Info("Task already cancelled.");
                return;
            }
            if (Status != TaskStatus.Enabled &&
                Status != TaskStatus.Selected)
                throw new InvalidTaskStatusException("Invalid status").SetInstanceId(InstanceId);
            Context.MessageCorrelationIdResolver.RemoveMapping(MessageCorrelationId, InstanceId);
            DefaultHandleTaskCancelled();
        }

        public override void Fail(string errorInformation)
        {
            base.Fail(errorInformation);
            Context.MessageCorrelationIdResolver.RemoveMapping(MessageCorrelationId, InstanceId);
        }

        public override void Complete(string finishedBy, Dictionary<string, object> updatedData)
        {
            base.Complete(finishedBy, updatedData);
            Context.MessageCorrelationIdResolver.RemoveMapping(MessageCorrelationId, InstanceId);
        }
    }
}
